﻿using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WeatherHistory.Api.CommandsQueries.Commands.Accounts.Delete;
using WeatherHistory.Api.CommandsQueries.Commands.Accounts.Update;
using WeatherHistory.Api.CommandsQueries.Queries.Accounts.GetOne;
using WeatherHistory.Api.CommandsQueries.Queries.Accounts.Search;
using WeatherHistory.Api.Filters;
using WeatherHistory.Shared.Exceptions;
using WeatherHistory.Shared.Validation;

namespace WeatherHistory.Api.Controllers;

/// <summary>
///     Контроллер для работы с аккаунтами пользователейЙ
/// </summary>
[ServiceFilter(typeof(AuthFilter))]
[Route("accounts")]
public class AccountsController : ApiControllerBase
{
    /// <summary>Получение информации об аккаунте по идентификатору аккаунта</summary>
    [HttpGet("{accountId:long}")]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(GetOneAccountsQueryResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<GetOneAccountsQueryResponse>> GetById([FromRoute] [GreaterThan(0L)] long accountId)
    {
        var request = new GetOneAccountsQueryRequest();
        request.AccountId = accountId;

        var result = await Mediator.Send(request);
        return Ok(result);
    }

    /// <summary>Поиск аккаунтов</summary>
    [HttpGet("search")]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(GetOneAccountsQueryResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<GetOneAccountsQueryResponse>> Search([FromQuery] SearchAccountsQueryRequest request)
    {
        var result = await Mediator.Send(request);
        return Ok(result);
    }


    /// <summary>Обновление информации об аккаунте</summary>
    [HttpPut("{accountId:long}")]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    [ProducesResponseType(typeof(GetOneAccountsQueryResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<UpdateAccountsCommandResponse>> Update([FromBody] UpdateAccountsCommandRequest request, [FromRoute] [GreaterThan(0L)] long accountId)
    {
        if (HttpContext.Request.Cookies["id"] != accountId.ToString()) throw new ForbiddenException("Попытка обновить чужой аккаунт");

        request.AccountId = accountId;

        var result = await Mediator.Send(request);
        return Ok(result);
    }

    /// <summary>Удаление аккаунта</summary>
    [HttpDelete("{accountId:long}")]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    [ProducesResponseType(typeof(GetOneAccountsQueryResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult> Delete([FromRoute] [GreaterThan(0L)] long accountId)
    {
        if (HttpContext.Request.Cookies["id"] != accountId.ToString()) throw new ForbiddenException("Попытка удалить чужой аккаунт");

        var request = new DeleteAccountsCommandRequest();
        request.AccountId = accountId;

        HttpContext.Response.Cookies.Delete("id");
        await Mediator.Send(request);
        return Ok();
    }
}